home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -serious- / programming / other / hexy / src / hexy_asm.s < prev    next >
Text File  |  1999-09-06  |  19KB  |  616 lines

  1.  
  2. ;*
  3.  * [!BGN - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  4.  *
  5.  * Program   : Hexy (Binary file viewer/editor for the Amiga.)
  6.  * Version   : 1.6
  7.  * File      : Work:Source/!WIP/HisoftProjects/Hexy/Hexy_asm.s
  8.  * Author    : Andrew Bell
  9.  * Copyright : Copyright © 1998-1999 Andrew Bell (See GNU GPL)
  10.  * Created   : Saturday 28-Feb-98 16:00:00
  11.  * Modified  : Sunday 22-Aug-99 23:31:45
  12.  * Comment   : 
  13.  *
  14.  * (Generated with StampSource 1.2 by Andrew Bell)
  15.  *
  16.  * [!END - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  17. ;*
  18.  
  19.  
  20. ;*
  21.  * -------------------------------------------------------------
  22.  * Amiga MC680x0 assembly support routines for Hexy v1.x
  23.  *
  24.  * Copyright © 1998-1999 Andrew Bell, <andrew.ab2000@bigfoot.com>
  25.  * --------------------------------------------------------------
  26.  *
  27.  * Hexy, binary file viewer and editor for the Amiga.
  28.  * Copyright (C) 1999 Andrew Bell
  29.  *
  30.  * Author's email address: andrew.ab2000@bigfoot.com
  31.  *
  32.  * This program is free software; you can redistribute it and/or modify
  33.  * it under the terms of the GNU General Public License as published by
  34.  * the Free Software Foundation; either version 2 of the License, or
  35.  * (at your option) any later version.
  36.  *
  37.  * This program is distributed in the hope that it will be useful,
  38.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  39.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  40.  * GNU General Public License for more details.
  41.  *
  42.  * You should have received a copy of the GNU General Public License
  43.  * along with this program; if not, write to the Free Software
  44.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  45.  *
  46.  * --------------------------------------------------------------
  47.  *
  48.  * This file created on Fri/27/Feb/1998
  49.  *
  50.  * This code makes Hexy that *little bit* faster than other hex viewers :-)
  51.  * 
  52.  * TODO: Optimize and more loop unrolling.
  53.  *
  54.  * NOTES: Use an assembler that can do full branch optimizations when
  55.  *        compiling this code.
  56.  *
  57.  *        060 users: There could be some 020 instructions in here that
  58.  *        have since been removed from the 060. I haven't had the chance
  59.  *        to check. If this is the case, then they'll have to be emulated
  60.  *        in software which will mean a drop in performance.
  61.  *
  62. ;*
  63.  
  64.                 incdir  AInc:
  65.                 include mymacros.i
  66.                 include exec/types.i
  67.                 include lvo/exec_lib.i
  68.                 include lvo/graphics_lib.i
  69.                 include lvo/utility_lib.i
  70.  
  71.                 SECTION text,code
  72.                 MC68020
  73.  
  74.                 IFD     _PHXASS_
  75.  
  76.                 TTL     Hexy_asm.s
  77.                 SYMDEBUG
  78.                 LINEDEBUG
  79.                 OPT     !
  80.  
  81.                 ENDC
  82.  
  83.                 rsreset
  84. VC_FileAddress  rs.l    1
  85. VC_FileLength   rs.l    1
  86. VC_CurrentPoint rs.l    1
  87. VC_RPort        rs.l    1
  88. VC_InitialYPos  rs.w    1
  89. VC_YAmount      rs.w    1
  90. VC_XPos         rs.w    1
  91. VC_Mode         rs.w    1
  92. VC_SIZEOF       rs.l    0
  93.  
  94.                 xdef    HEX.MainLoop    ; temp
  95.                 xdef    HEX.FilterLoop
  96.                 xdef    HEX.Insert
  97.                 xdef    HEX.TestClip
  98.                 xdef    HEX.InitClip
  99.                 xdef    HEX.InitCHEXPart
  100.                 xdef    HEX.ClipHEXPart
  101.                 xdef    HEX.Loop001
  102.                 xdef    HEX.ClipSPInit
  103.                 xdef    HEX.ClipStrPart
  104.                 xdef    HEX.Render
  105.  
  106. *---------------------------------------------------------------------------*
  107.  
  108.                 xdef    _AdjustView
  109.  
  110. _AdjustView:    PUSH    ALL             ; A0=VC, D0=Offset (Signed)
  111.  
  112.                 move.l  VC_CurrentPoint(a0),d1
  113.                 add.l   d0,d1
  114.                 bmi.b   .SetToZero
  115.  
  116.                 move.l  VC_FileLength(a0),d2
  117.                 beq.w   .Exit
  118.  
  119.                 subq.l  #1,d2           ; -1 so we can see last byte
  120.                 cmp.l   d2,d1
  121.                 ble.b   .SizeOK
  122.  
  123.                 move.l  d2,d1
  124.                 bra.b   .SizeOK
  125.  
  126. .SetToZero      moveq   #0,d1
  127. .SizeOK         move.l  d1,VC_CurrentPoint(a0)
  128.                 bsr.b   _UpdateView
  129.  
  130. .Exit           PULL    ALL
  131.                 rts
  132.  
  133. *---------------------------------------------------------------------------*
  134.  
  135. ; D7.w = lines left
  136. ; D6.w = current Y pixel
  137. ; A4.l = memory address
  138.  
  139.                 xref    _GfxBase
  140.                 xref    _SysBase
  141.                 xdef    _UpdateView
  142.  
  143.                 xref    _EditFlag               ; BOOL (16 bit)
  144.  
  145.                 xref    _Edit_WipeCursor        ; C code
  146.                 xref    _Edit_ShiftCursor
  147.  
  148. R_UPDATEVIEW    reg     d0-d1/d5-d7/a0-a1/a4-a6
  149.  
  150. _UpdateView:    PUSH    R_UPDATEVIEW            ; A0=VC, D0=MODE
  151.  
  152.                 move.l  a0,a5                   ; A4=VC
  153.  
  154.                 tst.w   _EditFlag
  155.                 beq.w   .NotActive
  156.  
  157.                 jsr     _Edit_WipeCursor        ; Call C code
  158.  
  159. .NotActive      moveq   #1,d0                   ; Black
  160.                 move.l  VC_RPort(a5),a1         ; RP
  161.                 SETLIB  _GfxBase,SetAPen
  162.  
  163.                 move.w  VC_YAmount(a5),d7       ; Amount of Y lines
  164.                 subq.w  #1,d7
  165.                 move.w  VC_InitialYPos(a5),d6   ; Current Y pixel
  166.                 move.l  VC_CurrentPoint(a5),d5  ; Current offset
  167.  
  168.                 move.l  VC_FileAddress(a5),d0
  169.                 beq.w   .Exit
  170.                 move.l  d0,a4
  171.                 add.l   d5,a4                   ; File Adr + Cur pnt
  172.  
  173.                 tst.w   VC_Mode(a5)
  174.                 beq.b   .HEX
  175. .ASCII          bsr.w   ASCII.Mode
  176.                 bra.b   .Exit
  177. .HEX            bsr.w   HEX.Mode
  178.  
  179. .Exit           tst.w   _EditFlag
  180.                 beq.b   .NotActive2
  181.  
  182.                 moveq   #0,d0
  183.                 jsr     _Edit_ShiftCursor       ; Call C code
  184.  
  185. .NotActive2     PULL    R_UPDATEVIEW
  186.                 rts
  187.  
  188.                 *-----------------------------------------------------------*
  189.  
  190.                 xdef    HEX.Mode
  191.  
  192. HEX.Mode        PUSH    ALL
  193.  
  194. HEX.MainLoop    cmp.l   VC_FileLength(a5),d5
  195.                 blt.b   HEX.DoPaste
  196.                 lea     EmptyLine(pc),a2
  197.                 bra     HEX.Render
  198.  
  199. HEX.DoPaste     lea     DumpLine(pc),a0         ; A0=Write
  200.                 move.l  a0,a2
  201.                 move.l  a4,a1                   ; A1=LONG read
  202.                 move.l  d5,d0                   ; Do Offset
  203.                 bsr.w   LongToHex
  204.                 move.b  #':',(a0)+
  205.  
  206.                 moveq   #' ',d2
  207.  
  208.                 ; Loop rolled out 5 times for speed
  209.  
  210.                 move.l  (a1)+,d0
  211.                 bsr.w   LongToHex
  212.                 move.b  d2,(a0)+
  213.  
  214.                 move.l  (a1)+,d0
  215.                 bsr.w   LongToHex
  216.                 move.b  d2,(a0)+
  217.  
  218.                 move.l  (a1)+,d0
  219.                 bsr.w   LongToHex
  220.                 move.b  d2,(a0)+
  221.  
  222.                 move.l  (a1)+,d0
  223.                 bsr.w   LongToHex
  224.                 move.b  d2,(a0)+
  225.  
  226.                 move.l  (a1)+,d0
  227.                 bsr.w   LongToHex
  228.                 move.b  d2,(a0)+
  229.  
  230.                 moveq   #19,d1                  ; Filter 20-1 bytes
  231. HEX.FilterLoop  move.b  (a4)+,d0
  232.                 bne.b   HEX.Insert
  233.  
  234.                 moveq   #1,d0
  235. HEX.Insert      move.b  d0,(a0)+
  236.                 dbf.w   d1,HEX.FilterLoop
  237.                 clr.b   (a0)+                   ; Terminate string
  238.  
  239.                 *-----------------------------------------------------------*
  240.  
  241.                 ; if (offset < len-20) then goto HEX.Render
  242.  
  243. HEX.TestClip    move.l  VC_FileLength(a5),d0    ; Use an An
  244.                 sub.l   #(4*5),d0
  245.                 cmp.l   d5,d0
  246.                 bge.b   HEX.Render
  247. HEX.InitClip    move.l  VC_FileLength(a5),d0
  248.                 sub.l   VC_CurrentPoint(a5),d0  ; (or d5)
  249.  
  250.                 ;moveq #(4*5),d1
  251.                 ;divul.l d1,d1:d0
  252.  
  253.                 xref    _UtilityBase
  254.  
  255.                 move.l  a6,-(sp)
  256.                 moveq   #(4*5),d1
  257.                 SETLIB  _UtilityBase,UDivMod32
  258.                 move.l  (sp)+,a6
  259.  
  260.                 moveq   #20,d0
  261.                 sub.l   d1,d0
  262.                 move.l  d0,d3
  263.                 move.l  d1,d4
  264.                 beq.b   HEX.Render
  265. HEX.InitCHEXPart
  266.                 move.l  d1,d0                   ; Get Dump Remainder
  267.  
  268.                 ;moveq #4,d1
  269.                 ;divul.l d1,d1:d0
  270.  
  271.                 move.l  a6,-(sp)
  272.                 moveq   #4,d1
  273.                 SETLIB  _UtilityBase,UDivMod32
  274.                 move.l  (sp)+,a6
  275.  
  276.                 move.l  d1,-(sp)                ; Store lrem
  277.                 moveq   #9,d1
  278.                 mulu.l d1,d0                    ; x9 ('00000000 ')
  279.                 move.l  (sp)+,d1                ; Restore remainder
  280.                 lsl.l   #1,d1                   ; x2
  281.                 add.l   d1,d0                   ; Add result to lrem
  282. HEX.ClipHEXPart lea     DumpLine(pc),a0         ;   to get wipe index
  283.                 lea     9(a0,d0.w),a0
  284.                 moveq   #(5*9),d1               ; -1 aswell
  285.                 sub.l   d0,d1
  286.                 beq.b   HEX.ClipSPInit
  287.                 bmi.b   HEX.ClipSPInit
  288.                 moveq   #' ',d0
  289. HEX.Loop001     move.b  d0,(a0)+
  290.                 subq.l  #1,d1
  291.                 bne.b   HEX.Loop001
  292.  
  293. HEX.ClipSPInit  lea     DumpLine(pc),a0
  294.                 lea     (6*9)(a0,d4.w),a0
  295.                 tst.l   d3
  296.                 beq.b   HEX.Invalid01
  297.                 bmi.b   HEX.Invalid01
  298.  
  299.                 moveq   #' ',d0
  300. HEX.ClipStrPart move.b  d0,(a0)+
  301.                 subq.l  #1,d3
  302.                 bne.b   HEX.ClipStrPart
  303.  
  304. HEX.Invalid01   *-----------------------------------------------------------*
  305.  
  306. HEX.Render      move.w  VC_XPos(a5),d0          ; Set X pix
  307.                 move.w  d6,d1                   ; Get Y pix
  308.                 move.l  VC_RPort(a5),a1         ; RP
  309.                 SETLIB  _GfxBase,Move
  310.  
  311.                 moveq   #HLENGTH,d0
  312.                 movea.l a2,a0                   ; String
  313.                 move.l  VC_RPort(a5),a1         ; RP
  314.                 DOLIB   Text
  315.  
  316.                 add.l   #20,d5
  317.                 addq.w  #8,d6
  318.                 dbf.w   d7,HEX.MainLoop
  319.  
  320. .Exit           PULL    ALL
  321.                 rts
  322.  
  323. *---------------------------------------------------------------------------*
  324.  
  325. ASCIIXAMOUNT    =       64
  326.  
  327.                 xdef    ASCII.Mode
  328.  
  329. ASCII.Mode      PUSH    ALL
  330.  
  331. ASCII.MainLoop  cmp.l   VC_FileLength(a5),d5
  332.                 blt.b   ASCII.DoPaste
  333.  
  334.                 lea     EmptyLine(pc),a2
  335.                 bra.b   ASCII.Render
  336.  
  337. ASCII.DoPaste   lea     DumpLine(pc),a0
  338.                 move.l  d5,d0
  339.                 bsr.w   LongToHex
  340.                 move.w  #': ',(a0)+
  341.                 moveq   #(ASCIIXAMOUNT-1),d1    ; Filter
  342. ASCII.FltLoop   move.b  (a4)+,d0
  343.                 bne.b   ASCII.Insert
  344.                 moveq   #1,d0
  345. ASCII.Insert    move.b  d0,(a0)+
  346.                 dbf.w   d1,ASCII.FltLoop
  347.                 lea     DumpLine(pc),a2
  348.  
  349.                 *-----------------------------------------------------------*
  350.  
  351.                 ; if (offset < len - ASCIIXAMOUNT) then goto ASCII.Render
  352.  
  353. ASCII.TestClip  move.l  VC_FileLength(a5),d0    ; Use an An
  354.                 sub.l   #ASCIIXAMOUNT,d0
  355.                 cmp.l   d5,d0
  356.                 bge.b   ASCII.Render
  357.  
  358. ASCII.InitClip  move.l  VC_FileLength(a5),d0
  359.                 sub.l   VC_CurrentPoint(a5),d0  ; (or d5)
  360.                 moveq   #ASCIIXAMOUNT,d1
  361.                 divul.l d1,d1:d0                ; Change this
  362.                 moveq   #ASCIIXAMOUNT,d0
  363.                 sub.l   d1,d0
  364.                 move.l  d0,d3
  365.                 move.l  d1,d4
  366.                 beq.b   ASCII.Render
  367.  
  368. ASCII.InitCHEXPart
  369.                 move.l  d1,d0                   ; Get Dump Remainder
  370.                 move.l  #ASCIIXAMOUNT,d2
  371.                 sub.l   d0,d2                   ; into index
  372.                 beq.b   ASCII.Render
  373.                 bmi.b   ASCII.Render
  374.  
  375. ASCII.Clip      lea     DumpLine(pc),a0
  376.                 lea     10(a0,d1.w),a0
  377.                 moveq   #' ',d0
  378. ASCII.Loop001   move.b  d0,(a0)+
  379.                 subq.l  #1,d2
  380.                 bne.b   ASCII.Loop001
  381.  
  382.                 *-----------------------------------------------------------*
  383.  
  384. ASCII.Render    move.w  VC_XPos(a5),d0          ; Set X pix
  385.                 move.w  d6,d1                   ; Get Y pix
  386.                 move.l  VC_RPort(a5),a1         ; RP
  387.                 SETLIB  _GfxBase,Move
  388.  
  389.                 moveq   #HLENGTH,d0
  390.                 movea.l a2,a0                   ; String
  391.                 move.l  VC_RPort(a5),a1         ; RP
  392.                 DOLIB   Text
  393.  
  394.                 add.l   #ASCIIXAMOUNT,d5
  395.                 addq.w  #8,d6
  396.                 dbf.w   d7,ASCII.MainLoop
  397.  
  398.                 PULL    ALL
  399.                 rts
  400.  
  401. *---------------------------------------------------------------------------*
  402.  
  403.                 xdef    LongToHex
  404.  
  405. ; void LongToHex( register __d0 ULONG, register __a1 UBYTE *Dest );
  406.  
  407. LongToHex:      PUSH    d0-d5
  408.  
  409.                 moveq   #7,d2                   ; 8 Digits
  410.                 moveq   #'0',d3
  411.                 moveq   #'9',d4
  412.                 moveq   #$f,d5
  413.  
  414. LTH.Loop        rol.l   #4,d0
  415.                 move.b  d0,d1
  416.                 and.b   d5,d1
  417.                 add.b   d3,d1
  418.                 cmp.b   d4,d1
  419.                 ble.b   LTH.NoLetter
  420.  
  421.                 addq.b  #7,d1
  422. LTH.NoLetter    move.b  d1,(a0)+
  423.                 dbra.w  d2,LTH.Loop
  424.  
  425.                 PULL    d0-d5                   ; A0 = End of string
  426.                 rts
  427.  
  428. *---------------------------------------------------------------------------*
  429.  
  430. HLENGTH         =       (9+9+9+9+9+9+20)
  431.  
  432. EmptyLine       dcb.b   HLENGTH,$20
  433.                 dc.b    0,0
  434. DumpLine        ds.b    128
  435.                 even
  436.  
  437. *---------------------------------------------------------------------------*
  438.  
  439.  
  440. ; NOTE: The following two routines have been taken from my own private
  441. ;       link library of routines.
  442.  
  443.  
  444. ******* AB.LIB/SearchMem ****************************************************
  445. *
  446. *   NAME   
  447. *       SearchMem - Search memory for a binary string.
  448. *
  449. *   SYNOPSIS
  450. *       Offset =  SearchMem( Mem, MemLen, CmpStr, CmpStrLen)
  451. *       D0                   A0   D0      A1      D1
  452. *
  453. *       __asm ULONG SearchMem( __A0 void *Mem,
  454. *                              __D0 ULONG MemLen,
  455. *                              __A1 UBYTE *CmpStr,
  456. *                              __D1 ULONG CmpStrLen );
  457. *
  458. *   FUNCTION
  459. *       Look for a binary string in memory.
  460. *
  461. *   INPUTS
  462. *       Mem       - Pointer to memory that will be searched.
  463. *       MemLen    - Length of memory to be searched.
  464. *       CmpStr    - Pointer to binary string to find.
  465. *       CmpStrLen - Length of binary string to find
  466. *
  467. *   RESULT
  468. *       ULONG Offset - Offset the binary string was found at (relative)
  469. *                      to the Mem parameter. If string was not found then
  470. *                      ~NULL is returned.
  471. *
  472. *   SEE ALSO
  473. *       AB.LIB/SearchMemRev()
  474. *
  475. *****************************************************************************
  476. * AB.LIB code module, created: 4/8/1997
  477. *
  478. * This file is copyright © 1997 Andrew Bell.
  479. *
  480. * __asm ULONG SearchMem(__A0 void *Mem, __D0 ULONG MemLen, __A1 UBYTE *CmpStr, __D1 ULONG CmpStrLen);
  481. *
  482.  
  483.                 xdef    SearchMem
  484.                 xdef    _SearchMem
  485.  
  486. SearchMem:
  487. _SearchMem:     PUSH    d1-d4/a0-a3
  488.  
  489.                 move.l  a0,-(sp)
  490.                 tst.l   d0              ; Check params
  491.                 beq.b   SM.Fail
  492.                 tst.l   d1
  493.                 beq.b   SM.Fail
  494.                 subq.l  #1,d1
  495.                 move.b  (a1)+,d2        ; Get first byte from match string
  496. SM.Loop         cmp.b   (a0)+,d2        ; Compare next byte
  497.                 bne.b   SM.NextByte
  498.                 move.l  a0,a2
  499.                 subq.l  #1,d4
  500.                 move.l  a1,a3
  501.                 move.l  d1,d3
  502.                 beq.b   SM.Matched
  503.                 move.l  d0,d4           ; << BEQ.B here >>
  504. SM.Loop2        cmpm.b  (a0)+,(a1)+     ; Match rest of string
  505.                 bne.b   SM.NoMatch
  506.                 subq.l  #1,d3
  507.                 beq.b   SM.Matched
  508.                 subq.l  #1,d4
  509.                 bne.b   SM.Loop2
  510.                 bra.b   SM.Fail
  511. SM.Matched      subq.l  #1,a2
  512.                 move.l  a2,d0
  513.                 sub.l   (sp),d0
  514.                 bra.b   SM.Fin
  515. SM.NoMatch      move.l  a3,a1
  516.                 move.l  a2,a0
  517. SM.NextByte     subq.l  #1,d0
  518.                 bne.b   SM.Loop
  519. SM.Fail         moveq.l #-1,d0
  520.  
  521. SM.Fin          addq.l  #4,sp
  522.                 PULL    d1-d4/a0-a3
  523.                 tst.l   d0              ; Handy when using asm
  524.                 rts
  525.  
  526.  
  527.  
  528.  
  529. ******* AB.LIB/SearchMemRev *************************************************
  530. *
  531. *   NAME   
  532. *       SearchMemRev - Search memory for a binary string, backwards.
  533. *
  534. *   SYNOPSIS
  535. *       Offset =  SearchMemRev( Mem, MemLen, CmpStr, CmpStrLen)
  536. *       D0                      A0   D0      A1      D1
  537. *
  538. *       __asm ULONG SearchMemRev( __A0 void *Mem,
  539. *                                 __D0 ULONG MemLen,
  540. *                                 __A1 UBYTE *CmpStr,
  541. *                                 __D1 ULONG CmpStrLen );
  542. *
  543. *   FUNCTION
  544. *       Look for a binary string in memory, backwards.
  545. *
  546. *   INPUTS
  547. *       Mem       - Pointer to memory that will be searched.
  548. *       MemLen    - Length of memory to be searched.
  549. *       CmpStr    - Pointer to binary string to find.
  550. *       CmpStrLen - Length of binary string to find
  551. *
  552. *   RESULT
  553. *       ULONG Offset - Offset the binary string was found at (relative)
  554. *                      to the Mem parameter. If string was not found then
  555. *                      ~NULL is returned.
  556. *
  557. *   SEE ALSO
  558. *       AB.LIB/SearchMem()
  559. *
  560. *****************************************************************************
  561. * AB.LIB code module, created: 4/8/1997
  562. *
  563. * This file is copyright © 1997 Andrew Bell.
  564. *
  565. * __asm ULONG SearchMemRev(__A0 void *Mem, __D0 ULONG MemLen, __A1 UBYTE *CmpStr, __D1 ULONG CmpStrLen);
  566. *
  567.  
  568.                 xdef    SearchMemRev
  569.                 xdef    _SearchMemRev
  570.  
  571. _SearchMemRev:
  572. SearchMemRev:   PUSH    d1-d4/a0-a3
  573.  
  574.                 move.l  a0,-(sp)
  575.                 tst.l   d0
  576.                 beq.b   SMR.Fail
  577.                 tst.l   d1
  578.                 beq.b   SMR.Fail
  579.                 sub.l   d1,d0
  580.                 bmi.b   SMR.Fail
  581.                 lea.l   (a0,d0.l),a0
  582.                 addq.l  #1,a0
  583.                 subq.l  #1,d1
  584.                 move.b  (a1)+,d2
  585. SMR.Loop        cmp.b   -(a0),d2
  586.                 bne.b   SMR.NextByte
  587.                 move.l  a0,a2
  588.                 addq.l  #1,a0
  589.                 move.l  a1,a3
  590.                 move.l  d1,d3
  591.                 beq.b   SMR.Matched
  592.                 move.l  d0,d4
  593. SMR.Loop2       cmp.b   (a0)+,(a1)+
  594.                 bne.b   SMR.NoMatch
  595.                 subq.l  #1,d3
  596.                 beq.b   SMR.Matched
  597.                 subq.l  #1,d4
  598.                 bne.b   SMR.Loop2
  599.                 bra.b   SMR.Fail
  600. SMR.Matched     move.l  a2,d0
  601.                 sub.l   (sp),d0
  602.                 bra.b   SMR.Fin
  603. SMR.NoMatch     move.l  a3,a1
  604.                 move.l  a2,a0
  605. SMR.NextByte    subq.l  #1,d0
  606.                 bpl.b   SMR.Loop
  607.  
  608. SMR.Fail        moveq.l #-1,d0
  609. SMR.Fin         addq.l  #4,sp
  610.                 PULL    d1-d4/a0-a3
  611.                 rts
  612.  
  613. *---------------------------------------------------------------------------*
  614.  
  615.                 end     ; For brain-dead assemblers :)
  616.